package ac.github.os.internal.core.action.location.particle

import ac.github.os.api.OriginSkillAPI
import ac.github.os.internal.core.config.StringConfig
import ac.github.os.internal.core.config.get
import ac.github.os.internal.core.holder.entity.ParticleHitHolder
import ac.github.os.internal.core.trigger.EntityTrigger
import ac.github.os.internal.session.Session
import org.bukkit.Bukkit
import org.bukkit.Particle
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import taboolib.common.platform.ProxyParticle
import taboolib.common.platform.function.adaptPlayer
import taboolib.common.platform.function.submit
import taboolib.common.platform.sendTo
import taboolib.common.util.Location
import taboolib.common.util.Vector
import taboolib.common5.Coerce
import taboolib.module.effect.ParticleSpawner
import taboolib.platform.util.toBukkitLocation
import java.awt.Color

class OriginParticleSpawner(private val session: Session, private val config: StringConfig) : ParticleSpawner {


    private val particle: ProxyParticle = config.get("enum",ProxyParticle.FLAME)!!
    private val count = config.get("count", 1)!!
    private val speed = config.get("speed", 0.0)!!
    private val offset = config.get("offset", listOf("0.0", "0.0", "0.0"))!!.map { Coerce.toDouble(it) }
    private val vector = config.get("vector", listOf("0.0", "0.0", "0.0"))!!.map { Coerce.toDouble(it) }
    private var data: ProxyParticle.Data? = null
    private val pitch = config.get<Float>("pitch")
    private val yaw = config.get<Float>("yaw")
    private val multiply = config.get<Double>("multiply")
    private val dMultiply = config.get<Double>("d.multiply")

    init {
        config.get<String>("block")?.let { data = ProxyParticle.BlockData(it) }
        config.get<String>("item")?.let {
            val split = it.split(":")
            data = ProxyParticle.ItemData(split[0], Coerce.toInteger(if (split.size == 1) "0" else split[1]))
        }
        config.get<String>("color")?.let {
            val split = it.split(" ").map { Coerce.toInteger(it) }
            val size = config.get("size", 0f)!!
            data = ProxyParticle.DustData(Color(split[0], split[1], split[2]), size)
        }
    }

    override fun spawn(location: Location) {
        location.add(offset[0], offset[1], offset[2])
        pitch?.let { location.pitch = it }
        yaw?.let { location.yaw = it }
        multiply?.let { location.multiply(it) }
        dMultiply?.let {
            val direction = location.direction
            direction.multiply(it)
            location.add(direction)
        }
        val loc = location.toBukkitLocation()
        config.get<List<String>>("on-hit")?.forEach { s ->
            loc.world!!.getNearbyEntities(loc, 1.0, 1.0, 1.0)
                .filterIsInstance<LivingEntity>()
                .forEach { OriginSkillAPI.cast(EntityTrigger(it), s, ParticleHitHolder(session.trigger)) }
        }
        loc.world!!.getNearbyEntities(loc, 100.0, 100.0, 100.0)
            .filterIsInstance<Player>().forEach {
                particle.sendTo(
                    adaptPlayer(it),
                    location,
                    Vector(vector[0], vector[1], vector[2]),
                    count,
                    speed,
                    data
                )
            }

    }
}